﻿using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Bases;
using Fuse8.ContentManagementFramework.Domain.Special;
using Fuse8.ContentManagementFramework.SystemFacade.Extensions;
using Fuse8.DomainFramework.Common;
using Fuse8.DomainFramework.DataAccess.SqlDatabase;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;

namespace Fuse8.ContentManagementFramework.DataAccess.SqlAccess.Mappers
{
    internal class CmsPageDataMapper : BaseSqlEntityDataMapper<CmsPage, int>
    {
        private static BaseSqlEntityDataMapper<CmsPage, int> _based = new BaseSqlEntityDataMapper<CmsPage, int>(new string[] { "SiteGroup", "Site", "SiteCategory", "SystemLanguage" });

        private static Dictionary<string, Func<object, IList<SqlParameter>>> _mappersTo = new Dictionary<string, Func<object, IList<SqlParameter>>>();

        static CmsPageDataMapper()
        {
            _mappersTo.Add("cms_sp_PageGetRoutes",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageGetRoutes", p, false);
                });
            _mappersTo.Add("cms_sp_PageGetFrontEndPage",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageGetFrontEndPage", p, false);
                });
            _mappersTo.Add("cms_sp_PageSelectAll",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageSelectAll", p, false);
                });
            _mappersTo.Add("cms_sp_PageSelectOne",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageSelectOne", p, false);
                });
            _mappersTo.Add("cms_sp_PagePreview",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PagePreview", p, false);
                });
            _mappersTo.Add("cms_sp_PageAdd", CreateMapperForPageCreate);
            _mappersTo.Add("cms_sp_PageSave", CreateMapperForPageUpdate);
            _mappersTo.Add("cms_sp_PageDelete",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageDelete", p, false)
                        .Concat(CreateMapperForPageDelete(p))
                        .ToList();
                });
            _mappersTo.Add("cms_sp_PageSelectAllByTemplateId",
                (p) =>
                {
                    return _based.MapTo("cms_sp_PageSelectAllByTemplateId", p, false);
                });
        }

        public CmsPageDataMapper()
            : base()
        { }

        public override IList<SqlParameter> MapTo(string sp, object parameter, bool isForCreate)
        {
            Guard.ArgumentNotEmpty(sp, "sp");

            return _mappersTo.ContainsKey(sp) ?
                _mappersTo[sp](parameter) :
                base.MapTo(sp, parameter, isForCreate);
        }

        public override CmsPage MapFrom(string sp, SqlDataReader reader)
        {
            Guard.ArgumentNotEmpty(sp, "sp");
            Guard.ArgumentNotNull(reader, "reader");

            var result = new CmsPage
            {
                Id = reader.GetInt32(reader.GetOrdinal("PageId")),
                SiteId = !reader.IsDBNull(reader.GetOrdinal("SiteId")) ?
                    reader.GetInt32(reader.GetOrdinal("SiteId")) :
                    new Nullable<int>(),
                SiteGroupId = !reader.IsDBNull(reader.GetOrdinal("SiteGroupId")) ?
                    reader.GetInt32(reader.GetOrdinal("SiteGroupId")) :
                    new Nullable<int>(),
                SystemLanguageId = !reader.IsDBNull(reader.GetOrdinal("SystemLanguageId")) ?
                   reader.GetInt32(reader.GetOrdinal("SystemLanguageId")) :
                   new Nullable<int>(),
                PublicPageId = reader.GetInt32(reader.GetOrdinal("PublicPageId")),
                PageName = reader.GetString(reader.GetOrdinal("PageName")),
                PageUrl = reader.GetString(reader.GetOrdinal("PageUrl")),
                PageTypeKey = reader.GetInt32(reader.GetOrdinal("PageTypeKey")),
                PageBehaviourTypeKey = reader.GetInt32(reader.GetOrdinal("PageBehaviourTypeKey")),
                UseFileCache = reader.GetBoolean(reader.GetOrdinal("UseFileCache")),
                CreatedBy = reader.GetInt32(reader.GetOrdinal("CreatedBy")),
                DateCreated = reader.GetDateTime(reader.GetOrdinal("DateCreated")),
                LastUpdatedBy = !reader.IsDBNull(reader.GetOrdinal("LastUpdatedBy")) ?
                    reader.GetInt32(reader.GetOrdinal("LastUpdatedBy")) :
                    new Nullable<int>(),
                DateLastUpdated = !reader.IsDBNull(reader.GetOrdinal("DateLastUpdated")) ?
                   reader.GetDateTime(reader.GetOrdinal("DateLastUpdated")) :
                   new Nullable<DateTime>(),
                PageKey = !reader.IsDBNull(reader.GetOrdinal("PageKey")) ?
                        reader.GetString(reader.GetOrdinal("PageKey")) :
                       null
            };

            if (sp.Equals("cms_sp_PageRevisionSelectAll", StringComparison.OrdinalIgnoreCase))
            {
                result.PageLevel = !reader.IsDBNull(reader.GetOrdinal("PageLevel")) ?
                    reader.GetInt16(reader.GetOrdinal("PageLevel")) :
                    0;

                result.IsVisible = !reader.IsDBNull(reader.GetOrdinal("IsVisible")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsVisible")) :
                    true;

                result.UserCreatedBy = !reader.IsDBNull(reader.GetOrdinal("UserCreatedBy")) ?
                  reader.GetString(reader.GetOrdinal("UserCreatedBy")) :
                  string.Empty;

                result.UserLastUpdatedBy = !reader.IsDBNull(reader.GetOrdinal("UserLastUpdatedBy")) ?
                    reader.GetString(reader.GetOrdinal("UserLastUpdatedBy")) :
                    string.Empty;

                result.IsPublished = !reader.IsDBNull(reader.GetOrdinal("IsPublished")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsPublished")) :
                    true;

                result.PublishStartDate = !reader.IsDBNull(reader.GetOrdinal("PublishStartDate")) ?
                    reader.GetDateTime(reader.GetOrdinal("PublishStartDate")) :
                    new Nullable<DateTime>();

                result.PublishEndDate = !reader.IsDBNull(reader.GetOrdinal("PublishEndDate")) ?
                    reader.GetDateTime(reader.GetOrdinal("PublishEndDate")) :
                    new Nullable<DateTime>();

                result.IsLatestRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestRevision")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsLatestRevision")) :
                    new Nullable<bool>();

                result.IsLatestCompletedRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestCompletedRevision")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsLatestCompletedRevision")) :
                    new Nullable<bool>();

                result.IsDeleted = !reader.IsDBNull(reader.GetOrdinal("IsDeleted")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsDeleted")) :
                    new Nullable<bool>();
            }

            if (sp.Equals("cms_sp_PageSelectAll", StringComparison.OrdinalIgnoreCase) ||
                sp.Equals("cms_sp_PageSelectChildPages", StringComparison.OrdinalIgnoreCase) ||
                sp.Equals("cms_sp_PageSelectParentPages", StringComparison.OrdinalIgnoreCase)) //TO DO: move sp names to settings
            {
                result.ParentPageId = !reader.IsDBNull(reader.GetOrdinal("ParentPageId")) ?
                       reader.GetInt32(reader.GetOrdinal("ParentPageId")) :
                       new Nullable<int>();

                result.PageLevel = !reader.IsDBNull(reader.GetOrdinal("PageLevel")) ?
                    reader.GetInt16(reader.GetOrdinal("PageLevel")) :
                    0;

                result.ChildrenCount = !reader.IsDBNull(reader.GetOrdinal("ChildrenCount")) ?
                    reader.GetInt32(reader.GetOrdinal("ChildrenCount")) :
                    0;

                result.IsVisible = !reader.IsDBNull(reader.GetOrdinal("IsVisible")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsVisible")) :
                    true;

                result.UserCreatedBy = !reader.IsDBNull(reader.GetOrdinal("UserCreatedBy")) ?
                  reader.GetString(reader.GetOrdinal("UserCreatedBy")) :
                  string.Empty;

                result.UserLastUpdatedBy = !reader.IsDBNull(reader.GetOrdinal("UserLastUpdatedBy")) ?
                    reader.GetString(reader.GetOrdinal("UserLastUpdatedBy")) :
                    string.Empty;

                result.IsPublished = !reader.IsDBNull(reader.GetOrdinal("IsPublished")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsPublished")) :
                    true;

                result.PublishStartDate = !reader.IsDBNull(reader.GetOrdinal("PublishStartDate")) ?
                    reader.GetDateTime(reader.GetOrdinal("PublishStartDate")) :
                    new Nullable<DateTime>();

                result.PublishEndDate = !reader.IsDBNull(reader.GetOrdinal("PublishEndDate")) ?
                    reader.GetDateTime(reader.GetOrdinal("PublishEndDate")) :
                    new Nullable<DateTime>();

                result.IsLatestRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestRevision")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsLatestRevision")) :
                    new Nullable<bool>();

                result.IsLatestCompletedRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestCompletedRevision")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsLatestCompletedRevision")) :
                    new Nullable<bool>();

                result.IsDeleted = !reader.IsDBNull(reader.GetOrdinal("IsDeleted")) ?
                    reader.GetBoolean(reader.GetOrdinal("IsDeleted")) :
                    new Nullable<bool>();

                var cmsTemplate = new CmsTemplate()
                                      {
                                          Id = !reader.IsDBNull(reader.GetOrdinal("Template_TemplateId")) ? reader.GetInt32(reader.GetOrdinal("Template_TemplateId")) : 0,
                                          TemplateName = !reader.IsDBNull(reader.GetOrdinal("Template_TemplateName")) ? reader.GetString(reader.GetOrdinal("Template_TemplateName")) : "",
                                          DefaultRegionId = !reader.IsDBNull(reader.GetOrdinal("Template_DefaultRegionId")) ? reader.GetInt32(reader.GetOrdinal("Template_DefaultRegionId")) : default(int?)
                                      };
                result.Template = cmsTemplate;
            }

            return result;
        }

        public override CmsPage MapFromMulti(string sp, SqlDataReader reader, CmsPage stepEntity, int index)
        {
            Guard.ArgumentNotEmpty(sp, "sp");
            Guard.ArgumentNotNull(reader, "reader");

            if (index == 0)
            {
                stepEntity = new CmsPage
                {
                    Id = reader.GetInt32(reader.GetOrdinal("PageId")),
                    PublicPageId = reader.GetInt32(reader.GetOrdinal("PublicPageId")),
                    ParentPageId = !reader.IsDBNull(reader.GetOrdinal("ParentPageId")) ?
                       reader.GetInt32(reader.GetOrdinal("ParentPageId")) :
                       new Nullable<int>(),
                    SiteId = !reader.IsDBNull(reader.GetOrdinal("SiteId")) ?
                        reader.GetInt32(reader.GetOrdinal("SiteId")) :
                        new Nullable<int>(),
                    SiteGroupId = !reader.IsDBNull(reader.GetOrdinal("SiteGroupId")) ?
                        reader.GetInt32(reader.GetOrdinal("SiteGroupId")) :
                        new Nullable<int>(),
                    SystemLanguageId = !reader.IsDBNull(reader.GetOrdinal("SystemLanguageId")) ?
                       reader.GetInt32(reader.GetOrdinal("SystemLanguageId")) :
                       new Nullable<int>(),
                    PageName = reader.GetString(reader.GetOrdinal("PageName")),
                    PageUrl = reader.GetString(reader.GetOrdinal("PageUrl")),
                    PageTypeKey = reader.GetInt32(reader.GetOrdinal("PageTypeKey")),
                    PageBehaviourTypeKey = reader.GetInt32(reader.GetOrdinal("PageBehaviourTypeKey")),
                    PageLevel = reader.GetInt16(reader.GetOrdinal("PageLevel")),
                    CreatedBy = reader.GetInt32(reader.GetOrdinal("CreatedBy")),
                    DateCreated = reader.GetDateTime(reader.GetOrdinal("DateCreated")),
                    LastUpdatedBy = !reader.IsDBNull(reader.GetOrdinal("LastUpdatedBy")) ?
                        reader.GetInt32(reader.GetOrdinal("LastUpdatedBy")) :
                        new Nullable<int>(),
                    DateLastUpdated = !reader.IsDBNull(reader.GetOrdinal("DateLastUpdated")) ?
                       reader.GetDateTime(reader.GetOrdinal("DateLastUpdated")) :
                       new Nullable<DateTime>(),
                    IsPublished = reader.GetBoolean(reader.GetOrdinal("IsPublished")),
                    PublishStartDate = !reader.IsDBNull(reader.GetOrdinal("PublishStartDate")) ?
                        reader.GetDateTime(reader.GetOrdinal("PublishStartDate")) :
                        new Nullable<DateTime>(),
                    PublishEndDate = !reader.IsDBNull(reader.GetOrdinal("PublishEndDate")) ?
                        reader.GetDateTime(reader.GetOrdinal("PublishEndDate")) :
                        new Nullable<DateTime>(),
                    Template = new CmsTemplate
                    {
                        Id = reader.GetInt32(reader.GetOrdinal("TemplateId")),
                        TemplateName = reader.GetString(reader.GetOrdinal("TemplateName")),
                        TemplateTypeKey = reader.GetInt32(reader.GetOrdinal("TemplateTypeKey")),
                        TemplateUrl = reader.GetString(reader.GetOrdinal("TemplateUrl"))
                    },
                    PageKey = !reader.IsDBNull(reader.GetOrdinal("PageKey")) ?
                        reader.GetString(reader.GetOrdinal("PageKey")) :
                       null
                };

                if (sp.Equals("cms_sp_PageSelectOne", StringComparison.OrdinalIgnoreCase))
                {
                    stepEntity.IsVisible = !reader.IsDBNull(reader.GetOrdinal("IsVisible")) ?
                        reader.GetBoolean(reader.GetOrdinal("IsVisible")) :
                        true;

                    stepEntity.UseFileCache = !reader.IsDBNull(reader.GetOrdinal("UseFileCache")) ?
                        reader.GetBoolean(reader.GetOrdinal("UseFileCache")) :
                        true;

                    stepEntity.IsLatestRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestRevision")) ?
                        reader.GetBoolean(reader.GetOrdinal("IsLatestRevision")) :
                        false;

                    stepEntity.IsLatestCompletedRevision = !reader.IsDBNull(reader.GetOrdinal("IsLatestCompletedRevision")) ?
                        reader.GetBoolean(reader.GetOrdinal("IsLatestCompletedRevision")) :
                        false;

                    stepEntity.WorkflowId = !reader.IsDBNull(reader.GetOrdinal("WorkflowId")) ?
                        reader.GetGuid(reader.GetOrdinal("WorkflowId")) :
                        new Nullable<Guid>();

                    stepEntity.IsPublished = !reader.IsDBNull(reader.GetOrdinal("IsPublished")) ?
                        reader.GetBoolean(reader.GetOrdinal("IsPublished")) :
                    true;

                    stepEntity.PublishStartDate = !reader.IsDBNull(reader.GetOrdinal("PublishStartDate")) ?
                        reader.GetDateTime(reader.GetOrdinal("PublishStartDate")) :
                        new Nullable<DateTime>();

                    stepEntity.PublishEndDate = !reader.IsDBNull(reader.GetOrdinal("PublishEndDate")) ?
                        reader.GetDateTime(reader.GetOrdinal("PublishEndDate")) :
                        new Nullable<DateTime>();

                    stepEntity.ParentPageName = !reader.IsDBNull(reader.GetOrdinal("ParentPageName")) ?
                       reader.GetString(reader.GetOrdinal("ParentPageName")) :
                       null;
                }

                if (sp.Equals("cms_sp_PageSelectOne", StringComparison.OrdinalIgnoreCase) ||
                    sp.Equals("cms_sp_PageGetFrontEndPage", StringComparison.OrdinalIgnoreCase))
                {
                    stepEntity.PageTitle = !reader.IsDBNull(reader.GetOrdinal("PageTitle")) ?
                       reader.GetString(reader.GetOrdinal("PageTitle")) :
                       null;

                    stepEntity.PageDescription = !reader.IsDBNull(reader.GetOrdinal("PageDescription")) ?
                       reader.GetString(reader.GetOrdinal("PageDescription")) :
                       null;

                    stepEntity.PageKeywords = !reader.IsDBNull(reader.GetOrdinal("PageKeywords")) ?
                       reader.GetString(reader.GetOrdinal("PageKeywords")) :
                       null;

                    stepEntity.IsVisible = reader.IsDBNull(reader.GetOrdinal("IsVisible")) || reader.GetBoolean(reader.GetOrdinal("IsVisible"));
                }
            }
            else if (index == 1)
            {
                var stepTemplateRegion = new CmsTemplateRegion
                {
                    Id = reader.GetInt32(reader.GetOrdinal("TemplateRegionId")),
                    TemplateRegionName = reader.GetString(reader.GetOrdinal("TemplateRegionName")),
                    TemplateId = reader.GetInt32(reader.GetOrdinal("TemplateId"))
                };

                if (!reader.IsDBNull(reader.GetOrdinal("PageControlId")))
                {
                    var stepTemplateRegionControl = new CmsPageControl
                    {
                        Id = reader.GetInt32(reader.GetOrdinal("PageControlId")),
                        PageId = reader.GetInt32(reader.GetOrdinal("PageId")),
                        TemplateRegionId = reader.GetInt32(reader.GetOrdinal("TemplateRegionId")),
                        PageControlTypeKey = reader.GetInt32(reader.GetOrdinal("PageControlTypeKey")),
                        PageControlViewValue = !reader.IsDBNull(reader.GetOrdinal("PageControlViewValue")) ?
                            reader.GetString(reader.GetOrdinal("PageControlViewValue")) :
                            null,
                        PageControlModelValue = !reader.IsDBNull(reader.GetOrdinal("PageControlModelValue")) ?
                            reader.GetString(reader.GetOrdinal("PageControlModelValue")) :
                            null,
                        PageControlOrder = reader.GetInt32(reader.GetOrdinal("PageControlOrder")),
                        PageControlContentId = !reader.IsDBNull(reader.GetOrdinal("PageControlContentId")) ?
                            reader.GetInt32(reader.GetOrdinal("PageControlContentId")) :
                            new Nullable<int>(),
                        ModuleId = !reader.IsDBNull(reader.GetOrdinal("ModuleId")) ?
                            reader.GetInt32(reader.GetOrdinal("ModuleId")) :
                            new Nullable<int>(),
                        PageControlContent = !reader.IsDBNull(reader.GetOrdinal("PageControlContent")) ?
                            reader.GetString(reader.GetOrdinal("PageControlContent")) :
                            null
                    };

                    if (sp.Equals("cms_sp_PageSelectOne", StringComparison.OrdinalIgnoreCase))
                    {
                        stepTemplateRegionControl.AdminCaption =
                            !reader.IsDBNull(reader.GetOrdinal("AdminCaption"))
                                ? reader.GetString(reader.GetOrdinal("AdminCaption"))
                                : null;
                    }

                    stepTemplateRegion.RegionControls =
                        new CmsPageControl[]
                        {
                            stepTemplateRegionControl
                        }
                        .ToList();
                }
                else
                {
                    stepTemplateRegion.RegionControls = new List<CmsPageControl>();
                }

                if (!stepEntity.Template.HasRegions)
                {
                    stepEntity.Template.TemplateRegions =
                        new CmsTemplateRegion[]
                        {
                            stepTemplateRegion
                        }
                        .ToList();
                }
                else
                {
                    stepEntity.Template.TemplateRegions =
                        stepEntity.Template.TemplateRegions
                        .Concat(
                            new CmsTemplateRegion[]
                            {
                                stepTemplateRegion
                            })
                        .ToList();

                    stepEntity.Template.TemplateRegions = stepEntity.Template.TemplateRegions
                        .Aggregate(
                            new CmsTemplateRegion[] { }.AsEnumerable(),
                            (working, next) =>
                            {
                                var current = working.FirstOrDefault(p => p.Id == next.Id);

                                if (current != null)
                                {
                                    if (next.HasControls)
                                    {
                                        if (current.HasControls)
                                        {
                                            current.RegionControls = current.RegionControls.Concat(next.RegionControls);
                                        }
                                        else
                                        {
                                            current.RegionControls = next.RegionControls;
                                        }
                                    }
                                }
                                else
                                {
                                    working = working
                                        .Concat(
                                            new CmsTemplateRegion[]
                                            {
                                                next
                                            })
                                        .ToList();
                                }

                                return working;
                            });
                }

                if (stepEntity.Template.HasRegions)
                {
                    stepEntity.PageControls =
                        stepEntity.Template.TemplateRegions
                        .SelectMany(p => p.RegionControls).ToList();
                }
            }
            else
            {
                throw new InvalidOperationException(string.Format("Stored procedure {0} can't return more than {1} result", sp, index));
            }

            return stepEntity;
        }

        private static IList<SqlParameter> CreateMapperForPageCreate(object parameter)
        {
            IList<SqlParameter> result = new List<SqlParameter>();

            var cmsPage = parameter as CmsPage;
            if (cmsPage != null)
            {
                result.Add(new SqlParameter("@PageId", cmsPage.Id) { Direction = ParameterDirection.ReturnValue });

                if (cmsPage.SiteId.HasValue)
                {
                    result.Add(new SqlParameter("SiteId", cmsPage.SiteId.Value));
                }
                if (cmsPage.SiteGroupId.HasValue)
                {
                    result.Add(new SqlParameter("SiteGroupId", cmsPage.SiteGroupId.Value));
                }
                if (cmsPage.SystemLanguageId.HasValue)
                {
                    result.Add(new SqlParameter("SystemLanguageId", cmsPage.SystemLanguageId.Value));
                }

                result.Add(new SqlParameter("TemplateId", cmsPage.TemplateId));

                if (cmsPage.ParentPageId.HasValue)
                {
                    result.Add(new SqlParameter("ParentPageId", cmsPage.ParentPageId.Value));
                }

                result.Add(new SqlParameter("PageTypeKey", cmsPage.PageTypeKey));
                result.Add(new SqlParameter("PageBehaviourTypeKey", cmsPage.PageBehaviourTypeKey));
                result.Add(new SqlParameter("PageName", cmsPage.PageName));
                result.Add(new SqlParameter("PageUrl", cmsPage.PageUrl));
                result.Add(new SqlParameter("IsVisible", cmsPage.IsVisible));
                result.Add(new SqlParameter("UseFileCache", cmsPage.UseFileCache));
                result.Add(new SqlParameter("CreatedBy", cmsPage.CreatedBy));
                result.Add(new SqlParameter("DateCreated", cmsPage.DateCreated));
                result.Add(new SqlParameter("PageTypeParameter", "Page")); //TO DO - remove hardcoded value
                result.Add(new SqlParameter("PageKey", cmsPage.PageKey));

                if (cmsPage.WorkflowId.HasValue)
                {
                    result.Add(new SqlParameter("WorkflowId", cmsPage.WorkflowId.Value));
                }

                if (cmsPage.IsLatestCompletedRevision.HasValue)
                {
                    result.Add(new SqlParameter("IsLatestCompletedRevision", cmsPage.IsLatestCompletedRevision.Value));
                }

                result.Add(new SqlParameter("IsPublished", cmsPage.IsPublished));
                result.Add(new SqlParameter("PublishStartDate", cmsPage.PublishStartDate));
                result.Add(new SqlParameter("PublishEndDate", cmsPage.PublishEndDate));
            }

            return result;
        }

        private static IList<SqlParameter> CreateMapperForPageUpdate(object parameter)
        {
            IList<SqlParameter> result = new List<SqlParameter>();

            var cmsPage = parameter as CmsPage;
            if (cmsPage != null)
            {
                result.Add(new SqlParameter("PageId", cmsPage.Id));

                if (cmsPage.SiteId.HasValue)
                {
                    result.Add(new SqlParameter("SiteId", cmsPage.SiteId.Value));
                }
                if (cmsPage.SiteGroupId.HasValue)
                {
                    result.Add(new SqlParameter("SiteGroupId", cmsPage.SiteGroupId.Value));
                }
                if (cmsPage.SystemLanguageId.HasValue)
                {
                    result.Add(new SqlParameter("SystemLanguageId", cmsPage.SystemLanguageId.Value));
                }

                result.Add(new SqlParameter("TemplateId", cmsPage.TemplateId));

                if (cmsPage.ParentPageId.HasValue)
                {
                    result.Add(new SqlParameter("ParentPageId", cmsPage.ParentPageId.Value));
                }

                result.Add(new SqlParameter("PageBehaviourTypeKey", cmsPage.PageBehaviourTypeKey));
                result.Add(new SqlParameter("PageName", cmsPage.PageName));
                result.Add(new SqlParameter("PageUrl", cmsPage.PageUrl));
                result.Add(new SqlParameter("IsVisible", cmsPage.IsVisible));
                result.Add(new SqlParameter("UseFileCache", cmsPage.UseFileCache));
                result.Add(new SqlParameter("PageTitle", cmsPage.PageTitle));
                result.Add(new SqlParameter("PageDescription", cmsPage.PageDescription));
                result.Add(new SqlParameter("PageKeywords", cmsPage.PageKeywords));
                result.Add(new SqlParameter("LastUpdatedBy", cmsPage.LastUpdatedBy));
                result.Add(new SqlParameter("DateLastUpdated", cmsPage.DateLastUpdated));
                result.Add(new SqlParameter("CreatedBy", cmsPage.CreatedBy));
                result.Add(new SqlParameter("DateCreated", cmsPage.DateCreated));
                result.Add(new SqlParameter("PageTypeParameter", "Page")); //TO DO - remove hardcoded value
                result.Add(new SqlParameter("ContentTypeParameter", "Content")); //TO DO - remove hardcoded value
                result.Add(new SqlParameter("PageContentTypeParameter", CmsContentType.PageContentSystemContentType));
                result.Add(new SqlParameter("PageControlTypeParameter", "PageControl")); //TO DO - remove hardcoded value
                result.Add(new SqlParameter("PageKey", cmsPage.PageKey));

                if (cmsPage.WorkflowId.HasValue)
                {
                    result.Add(new SqlParameter("WorkflowId", cmsPage.WorkflowId.Value));
                }
                if (cmsPage.IsLatestCompletedRevision.HasValue)
                {
                    result.Add(new SqlParameter("IsLatestCompletedRevision", cmsPage.IsLatestCompletedRevision.Value));
                }

                result.Add(new SqlParameter("IsPublished", cmsPage.IsPublished));

                if (cmsPage.PublishStartDate.HasValue)
                {
                    result.Add(new SqlParameter("PublishStartDate", cmsPage.PublishStartDate.Value));
                }
                if (cmsPage.PublishEndDate.HasValue)
                {
                    result.Add(new SqlParameter("PublishEndDate", cmsPage.PublishEndDate.Value));
                }

                result.Add(new SqlParameter("NewPageId", cmsPage.Id) { Direction = ParameterDirection.ReturnValue }); ;
            }

            return result;
        }

        private static IList<SqlParameter> CreateMapperForPageDelete(object parameter)
        {
            IList<SqlParameter> result = new List<SqlParameter>();

            result.Add(new SqlParameter("PageTypeParameter", "Page")); //TO DO - remove hardcoded value

            return result;
        }

        public override void MapFrom(string sp, CmsPage entity, Dictionary<string, object> values)
        {
            if (sp == "cms_sp_PageAdd" && values.ContainsKey("PageId"))
            {
                entity.Id = Convert.ToInt32(values["PageId"]);
            }
            else
            {
                base.MapFrom(sp, entity, values);
            }
        }
    }
}